using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;


namespace RStudio.UnitSingleton
{
    /// <summary>
    /// 游戏服务中心
    /// </summary>
    public class GameService : IGameServiceLocater, IDisposable
    {
        /// <summary>
        /// 线程安全的单例
        /// </summary>
        private static readonly Lazy<GameService> _instance = new(() => new GameService());

        /// <summary>
        /// 线程同步锁
        /// </summary>
        private readonly object _lockObject = new();

        /// <summary>
        /// 访问接口
        /// </summary>
        public static IGameServiceLocater Instance => _instance.Value;

        /// <summary>
        /// 服务容器
        /// </summary>
        private readonly Dictionary<Type, IGameService> _services = new();

        private GameService() { }




        public T GetService<T>() where T : class, IGameService
        {
            lock (_lockObject)
            {
                if (_services.TryGetValue(typeof(T), out var service))
                {
                    return service as T;
                }

                throw new InvalidOperationException($"服务 {typeof(T).Name} 未注册");
            }
        }
        public bool IsServiceRegistered<T>() where T : class, IGameService
        {
            return _services.ContainsKey(typeof(T));
        }
        public void Register<T>(T service) where T : class, IGameService
        {
            if (service == null)
            {
                throw new ArgumentNullException(nameof(service));
            }

            lock (_lockObject)
            {
                _services[service.GetType()] = service ?? throw new ArgumentNullException(nameof(service));
                service.Init();
            }
        }
        public void Unregister<T>() where T : class, IGameService
        {
            lock (_lockObject)
            {
                if (_services.TryGetValue(typeof(T), out var service))
                {
                    service.Dispose();
                    _services.Remove(typeof(T));
                }
            }
        }
        public void Dispose()
        {
            lock (_lockObject)
            {
                var sortedServices = new List<IGameService>(_services.Values).OrderByDescending(s=>s.Priority).ToList();

                foreach (var service in sortedServices)
                {
                    try
                    {
                        service.Dispose();
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError($"服务 {service.GetType().Name} 释放时发生错误: {ex.Message}");
                    }
                }
                _services.Clear();
            }
        }



        /// <summary>
        /// 注册|批量服务
        /// </summary>
        public void Registers(params IGameService[] services) 
        {
            if (services == null) return;
            if (services.Length == 0) return;

            var sortedServices = services
               .OrderBy(s => s.Priority)
               .GroupBy(s => s.GetType())
               .Select(g => g.First())
               .ToList();

            lock (_lockObject)
            {
                foreach (var service in sortedServices)
                {
                    this.Register(service);
                }
            }        
        }
    }
}
